<?php

namespace control;

/*
*工序报工类
*/

class processReportClass extends adIndexClass
{
    private const table = 'process_report';
    private const tableMx = 'process_report_detail';
    private const tableStaff = 'process_report_staff';
    private const page = 'processReport';
    private const title = '工序报工';
    public array $stateOption = ['草稿', '待确认', '已确认'];

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'orderNo'          => [
                        'name'  => "报工单号",
                        'width' => 150,
                        'sort' => 1,
                    ],
                    'sourceOrder'  => [
                        'name'  => '生产派工单号/生产流转卡单号',
                        'width' => 150,
                    ],
                    'line'         => [
                        'name'  => '生产线',
                        'width' => 150,
                    ],
                    'process'          => [
                        'name'  => '工序',
                        'width' => 150,
                    ],
                    'equipment'          => [
                        'name'  => '关联设备',
                        'width' => 60,
                    ],
                    'teamNo'          => [
                        'name'  => '班次',
                        'width' => 150,
                        'sort' => 1,
                    ],
                    'team'          => [
                        'name'  => '班组',
                        'width' => 120,
                    ],
                    'code'          => [
                        'name'  => '产品编码',
                        'width' => 150,
                    ],
                    'name'          => [
                        'name'  => '产品名称',
                        'width' => 150,
                    ],
                    'model'          => [
                        'name'  => '规格型号',
                        'width' => 150,
                    ],
                    'unit'          => [
                        'name'  => '单位',
                        'width' => 60,
                    ],
                    'num'          => [
                        'name'  => '计划产量',
                        'width' => 120,
                    ],
                    'yield'          => [
                        'name'  => '完成产量',
                        'width' => 120,
                    ],
                    'goodNum'          => [
                        'name'  => '良品数量',
                        'width' => 120,
                    ],
                    'badNum'          => [
                        'name'  => '不良品数量',
                        'width' => 120,
                        'sort' => 1,
                    ],
                    'stid'          => [
                        'name'  => '报工人',
                        'width' => 100,
                    ],
                    'state'          => [
                        'name'  => '状态',
                        'width' => 100,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        if (optionSettingClass::getSettingItem('生产', 'productCtrlMethod') == 'productCard') {
            $title = '生产流转卡单号';
        } else {
            $title = '生产派工单号';
        }
        $array = [
            [
                [
                    "状态" => checkbox(array('name' => 'state', 'value' => $this->stateOption, 'checked' => $this->get('state') ? [$this->get('state')] : [])),
                ],
                [
                    "报工单号" => text(array("name" => "orderNo")),
                    $title   => text(array("name" => "machiningOrderNo")),
                    '班组' => selectMultiple(array("name" => "teamId", 'where' => "coid = '" . self::$coid . "'", "table" => "team", 'sqlField' => 'name', 'sqlId' => 'id', 'class' => 'width200')),
                ],
                [
                    '工序'  => selectMultiple(array("name" => "processId", 'where' => "coid = '" . self::$coid . "'", "table" => "process", 'sqlField' => 'name', 'sqlId' => 'id', 'class' => 'width200')),
                    "产品名称" => text(array('name' => 'materialName')),
                    '班次' => select(array('name' => 'teamType', 'option' => explode('，', para('teamType')))),
                ],
                [
                    "班次日期" => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                ]
            ]
        ];
        if ($this->power(self::page, "seeAll")) {
            $array[0][3]['申请人'] = selectMultiple(array("name" => "stid", "table" => "staff", 'sqlField' => 'name', 'sqlId' => 'stid', 'class' => 'width200'));
        }
        //生成查询表单
        $html = $this->tableShow($array,1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*行政人事-出差记录-查询条件*/
    public function home()
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        $url      = root . "control/adIndex.html?cla=" . $this->get('cla');
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"layer('".self::page."','edit')\" class='spanButton'>新增</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        }
        if ($this->power(self::page, "confirm")) {
            $button .= "<span onclick=\"layer('{$this->get('cla')}', 'batchConfirm', {'act': 'del'})\" class='spanButton'>批量确认</span>\n";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }



    /*行政人事-出差记录-查询结果*/
    public function homeSearch()
    {
        //全等查询数组
        $equal = array(
            'classify'  => '工序报工',
            'coid'      => self::$coid,
            "teamType"  => $this->post('teamType'),
            "processId" => $this->post('processId'),
            "teamId"    => $this->post('teamId'),
        );
        //like查询数组
        $like = array(
            "orderNo" => $this->post('orderNo'),//单据编号
        );
        //初始化
        $and       = "";
        $mAnd      = '';
        $strWhere  = '';
        $sendWhere = '';
        if ($this->post('machiningOrderNo')) {
            if (optionSettingClass::getSettingItem('生产', 'productCtrlMethod') == 'productCard') {
                $and .= " and sendId in (select id from machining_card_detail where orderId in (select id from machining_card where  coid = '" . self::$coid . "' and orderNo like '%" . $this->post('machiningOrderNo') . "%'))";
            } else {
                $and .= " and sendId in (select id from machining_send_order where  coid = '" . self::$coid . "' and orderNo like '%" . $this->post('machiningOrderNo') . "%')";
            }
        }
        if ($this->post('materialName')) {
            $mAnd = " and name like '%" . $this->post('materialName') . "%'";
        }
        if ($mAnd) {
            $and .= " and  materialId in (select id from material where coid = '" . self::$coid . "' {$mAnd})";
        }
        if ($this->post('createTime')) {
            $and       .= self::timeComparison($this->post('createTime'), field: 'teamNo');
            $strWhere  .= self::timeComparison($this->post('createTime'), field: 'teamNo');
            $sendWhere .= self::timeComparison($this->post('createTime'), field: 'recordDate');
        }
        if ($this->post('state')) {
            //单据日期
            $and .= " and state in ('" . implode("','", $this->post('state')) . "')";
        }
        //如果没有查看所有员工请假记录的权限
        if (!$this->power(self::page, "seeAll")) {
            $and .= $this->seeSelf(self::page);
        }
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        $page  = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        $url      = root . "control/adIndex.html?cla=" . $this->get('cla') . "";

        //获取记录
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "box"    => array("name" => "listId", "value" => $array['id']),
                "edit"   => $array['state'] == '已确认' ? [] : array("title" => "编辑", "click" => "layer('" . self::page . "','edit',{id:'" . $array['id'] . "'})"),
                "detail" => array("title" => self::title . "详情", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=detail&id=" . $array['id'] . "')"),
            );
            if ($array['sourceTable'] == 'machining_card_detail') {
                $machining_card_detail = query('machining_card_detail', "id = '$array[sendId]'");
                $sourceOrder           = query('machining_card', "id = '$machining_card_detail[orderId]'");
            } else {
                $sourceOrder = query('machining_send_order', "id = '$array[sendId]'");
            }
            $material = query('material', "id = '$array[materialId]'");
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'sourceOrder':
                        $row[] = $sourceOrder['orderNo'];
                        break;
                    case 'line':
                        $line     = query('product_line', "id = '$array[lineId]'");
                        $row[] = $line['workshop'] . '-' . $line['name'];
                        break;
                    case 'process':
                        $process  = query('process', "id = '$array[processId]'");
                        $row[] = $process['name'];
                        break;
                    case 'team':
                        $team     = query('team', "id = '$array[teamId]'");
                        $row[] =  $team['name'];
                        break;
                    case 'equipment':
                        $row[] =  equipmentClass::getName($array['deviceId']);
                        break;
                    case 'teamNo':
                        $row[] =  $array['teamNo'] . ' ' . $array['teamType'];
                        break;
                    case 'num':
                        $row[] = self::lostZero($array['orderNum'], 'numPrecision');
                        break;
                    case 'yield':
                    case 'badNum':
                        $row[] = self::lostZero($array[$key], 'numPrecision');
                        break;
                    case 'goodNum':
                        $row[] = $array['yield'] - $array['badNum'];
                        break;
                    case 'stid':
                        $row[] = self::findStaff($array['stid']);
                        break;
                    case 'code':
                    case 'name':
                    case 'model':
                    case 'unit':
                        $row[] = $material[$key];
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = "";
        //合计
        $totalPlan = find([
                'table'  => "machining_send_order",
                'field'  => "IFNULL(sum(num),0) as num",
                'single' => " coid = '" . self::$coid . "' and classify = '生产派工' and state = '已确认' $sendWhere ",
            ])['num'] * 1 ?? 0;

        $totalPlan      += find([
                'table'  => "machining_card as a join machining_card_detail as b on a.id = b.orderId",
                'field'  => "IFNULL(sum(a.num),0) as num",
                'single' => " a.coid = '" . self::$coid . "' $sendWhere",
            ])['num'] * 1 ?? 0;
        $totalYield     = find([
                'table'  => "process_report",
                'field'  => "IFNULL(sum(yield),0) as num",
                'single' => " 1=1 {$strWhere} and state = '已确认'  ",
            ])['num'] * 1 ?? 0;
        $completionRate = $totalPlan > 0 ? round($totalYield / $totalPlan, 2) * 100 : 0;
        $plan_tip       = componentClass::tipComponent('生产流转卡+生产派工单（已确认）数量', '?');
        $completion_tip = componentClass::tipComponent('已确认报工数量', '?');
        $button         .= saleIncomeClass::titleSpan('计划产量', self::lostZero($totalPlan, 'numPrecision') . $plan_tip);
        $button         .= saleIncomeClass::titleSpan('完成产量', self::lostZero($totalYield, 'numPrecision') . $completion_tip);
        $button         .= saleIncomeClass::titleSpan('完成率', $completionRate . '%');

        $totalQuery = find([
            'table'  => self::table,
            'single' => $where,
            'field'  => "ifnull(sum(orderNum),0) as orderNum,ifnull(sum(yield),0) as yield,ifnull(sum(badNum),0) as badNum",
        ]);
        $total    = [
            'num'        => self::lostZero($totalQuery['orderNum'], 'numPrecision'),
            'yield'        => self::lostZero($totalQuery['yield'], 'numPrecision'),
            'badNum'        => self::lostZero($totalQuery['badNum'], 'numPrecision'),
            'goodNum'        => self::formattingFigure($totalQuery['yield'] - $totalQuery['badNum'], 'numPrecision'),
        ];
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
            "total"       => $total,
        ));
        //返回
        $json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $li . "</form>" . $page['button'] . clear;
        return json_encode($json, 320);
    }

    /**
     * 批量确认
     */
    public function batchConfirm(): bool|string
    {
        //生成表单
        $html = $this->layerEdit(array(
            "table"      => array(
                array(
                    "提示：" => "是否批量确认所选数据？",
                ),
            ),
        ));
        //返回
        return $this->layer(array("title" => "批量确认", "height" => 165, "html" => $html, 'formTwo' => 'listForm'));
    }

    /**
     *  批量确认
     */
    public function batchConfirmEdit(): bool|string
    {
        $idArr = $this->post('listId');
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有" . self::title . "的编辑权限";
        } elseif (empty($idArr) || !is_array($idArr)) {
            $json['warn'] = "请选择数据";
        } else {
            $field        = [
                'state'       => '已确认',
                'checkId'     => self::$stid,
                'confirmTime' => $this->time,
            ];
            $text         = '';
            $json['warn'] = '';
            $x            = 0;

            foreach ($idArr as $id) {
                $info = query(self::table, "id = '$id'");
                if (empty($info['yield']) || $info['yield'] <= 0) {
                    $json['warn'] = "报工单【{$info['orderNo']}】的产量为0";
                    break;
                } elseif (empty($info['teamNo']) || empty($info['teamType'])) {
                    $json['warn'] = "报工单【{$info['orderNo']}】未选择班次";
                    break;
                } elseif (empty($info['teamId'])) {
                    $json['warn'] = "报工单【{$info['orderNo']}】未选择班组";
                    break;
                }
                if ($info['state'] != '已确认') {
                    $this->startTrans();
                    $json['warn'] = update(array('table' => self::table, 'field' => $field, 'where' => " id  = '$id'"));
                    if ($info['valuationType'] == '班组计件') {
                        $teamMx = find(array('table' => 'team_detail', "where" => "orderId = '$info[teamId]' order by list asc"));
                        foreach ($teamMx['array'] as $array) {
                            $warn = static::insert(array(
                                'table' => self::tableStaff,
                                'field' => [
                                    'id'      => self::getId(),
                                    'orderId' => $info['id'],
                                    'stid'    => $array['stid'],
                                    'coid'    => self::$coid,
                                ],
                            ));
                            if ($warn != '新增成功') {
                                $json['warn'] = $warn;
                                break;
                            }
                        }
                    }
                    /*********生成工序库存变动记录************/
                    $bool = $this->setInventory($info);
                    if ($bool !== true) {
                        $json['warn'] = $bool;
                    }
                    /************尾工序自动生成生产入库单***************/
                    $routingMx = query('routing_detail', "id = '$info[routingMxId]'");
                    $routing   = query('routing', "id = '$routingMx[orderId]'");
                    //尾工序
                    $endRoutingDetail = query('routing_detail', "orderId = '$routing[id]' order by list desc");
                    $state            = '';
                    if ($routingMx['id'] == $endRoutingDetail['id'] && $routing['endProcessIn'] == '是') {
                        $mainId = suiji();
                        $userNo = codeTemplateClass::generateCode('machiningInOrder', [
                            'prefix' => 'SCRK' . date('Ymd', strtotime($info['teamNo'])),
                            'table'  => self::table,
                            'field'  => 'orderNo',
                            'where'  => " and coid = '" . self::$coid . "'",
                        ], []);

                        if ($info['sourceTable'] == 'machining_card_detail') {
                            $machining_card_detail = query('machining_card_detail', "id = '$info[sendId]'");
                            $sourceOrder           = query('machining_card', "id = '$machining_card_detail[orderId]'");
                            $machiningOrderMxId    = $sourceOrder['sourceMxId'];
                        } else {
                            $sourceOrder        = query('machining_send_order', "id = '$info[sendId]'");
                            $machiningOrderMxId = $sourceOrder['machiningOrderMxId'];
                        }
                        $machiningOrderMx = query('machining_order_mx', "id = '$machiningOrderMxId'");
                        $material         = query('material', "id = '$info[materialId]'");
                        $state            = $material['warehouse'] ? '已确认' : '草稿';
                        $warn             = static::insert(array(
                            'table' => 'machining_in_order',
                            'field' => [
                                'id'         => $mainId,
                                'orderNo'    => $userNo,
                                'state'      => $state,
                                'coid'       => self::$coid,
                                'stid'       => $this->control['stid'],
                                'text'       => '尾工序自动生成',
                                'lineId'     => $info['lineId'],
                                'manager'    => $info['stid'],
                                'recordDate' => $info['teamNo'],
                            ],
                        ));
//						if (empty($material['warehouse'])) {
//							$json['warn'] = '未找到物料【' . materialClass::getName($material['id']) . '】的默认仓库';
//						}
                        if ($warn !== '新增成功') {
                            $json['warn'] = $warn;
                        }
                        $warn = static::insert([
                            "table" => 'machining_in_order_detail',
                            "field" => [
                                'id'          => suiji(),
                                'orderId'     => $mainId,
                                'coid'        => self::$coid,
                                'sourceId'    => $machiningOrderMxId,
                                'materialId'  => $info['materialId'],
                                'num'         => $info['yield'],
                                'unit'        => $sourceOrder['unit'],
                                'warehouseId' => $material['warehouse'],
                                'batch'       => $machiningOrderMx['batch'],
                                'reportId'    => $info['id']
                            ],
                        ]);
                        if ($warn !== '新增成功') {
                            $json['warn'] = $warn;
                        }
                    }

                    $bool = $this->qualityOrder($info['id']);
                    if ($bool !== true) {
                        $json['warn'] = "【{$info['orderNo']}】:" . $bool;
                    }
                    if ($json['warn'] == '更新成功') {
                        $this->commitTrans();
                        if ($routingMx['id'] == $endRoutingDetail['id'] && $routing['endProcessIn'] == '是' && $state == '已确认') {
                            $mainId                = $mainId ?? '';
                            $machiningOrder        = query('machining_in_order', "id = '$mainId'");
                            $machiningInOrderClass = new machiningInOrderClass();
                            $machiningInOrderClass->insertInventory($machiningOrder, false);
                        }
                        $x++;
                        $text .= "【{$info['orderNo']}】状态修改为：已确认<br>";
                        auditClass::operateRecord($info['id'], '工序报工', '确认');
                    } else {
                        $this->rollback();
                        $text .= "【{$info['orderNo']}】更新失败<br>";
                        break;
                    }
                }else{
                    $text .= "【{$info['orderNo']}】已确认，请勿重复操作<br>";
                }
            }
            if ($text) {
                //添加日志
                $text = $this->control['name'] . "批量确认了" . self::title . "如下：" . $text;
                $this->logText(["type" => self::page, "text" => $text]);
            }
            //返回
            $_SESSION['warn'] = '成功操作' . $x . '条数据';
            $json['warn']     = 2;
        }
        //返回
        return json_encode($json, 320);
    }

    /**
     * 编辑
     *
     * @return string
     */
    public function edit()
    {
        $id          = $this->post('id') ?: self::getId();
        $info        = query(self::table, " id = '" . $id . "' ");
        $clockRuleTr = '';
        $preProcess  = '';
        if ($info['sourceTable'] == 'machining_card_detail') {
            $machining_card_detail = query('machining_card_detail', "id = '$info[sendId]'");
            $sourceOrder           = query('machining_card', "id = '$machining_card_detail[orderId]'");
            $process               = query('process', "id = '$machining_card_detail[processId]'");
            //取上一工序
            $preCardDetail = query(
                'machining_card_detail',
                "orderId = '$machining_card_detail[orderId]' and list < $machining_card_detail[list] order by list desc"
            );
            if (!empty($preCardDetail['id'])) {
                $preProcess   = query('process', "id = '$preCardDetail[processId]'");
                $preReportNum      = find(array('table' => self::table, "single" => "sendId = '$preCardDetail[id]' and state = '已确认'", 'field' => "ifnull(sum((yield-badNum)),0) as num"))['num'];
                $preReportNum = self::lostZero($preReportNum, 'numPrecision');
                $preProcess   = "，上工序【{$preProcess['name']}】报工合格{$preReportNum} " . $sourceOrder['unit'];
            }
            $reportNum = find(array('table' => self::table, 'where' => "sendId = '$machining_card_detail[id]'", 'sum' => "yield"));
        } else {
            $sourceId    = $this->post('sourceId');//派工单跳转过来
            $sourceOrder = query('machining_send_order', "id = '$info[sendId]'");
            $reportNum   = find(array('table' => self::table, 'where' => "sendId = '$sourceOrder[id]'", 'sum' => "yield"));
            if ($sourceId) {
                //从派工单那边生成报工
                $sourceOrder           = query('machining_send_order', "id = '$sourceId'");
                $info['teamId']        = $sourceOrder['teamId'];
                $info['sendId']        = $sourceOrder['id'];
                $info['processId']     = $sourceOrder['processId'];
                $routing_detail        = query('routing_detail', "id = '$sourceOrder[routingMxId]'");
                $info['valuationType'] = $routing_detail['valuationType'];
                $reportNum             = find(array('table' => self::table, 'where' => "sendId = '$sourceOrder[id]'", 'sum' => "yield"));
                $info['yield']         = self::formattingFigure($sourceOrder['num'] - $reportNum, 'numPrecision');
                $info['deviceId'] = $sourceOrder['deviceId'];
            }
            $process = query('process', "id = '$info[processId]'");
        }
        $defectOption = $process['id'] ? explode('，', $process['defectType']) : [];
        $result       = find(array('table' => self::tableMx, 'where' => " orderId = '$info[id]' order by list asc"));
        if (is_array($result['array']) && count($result['array']) > 0) {
            foreach ($result['array'] as $k => $array) {
                if ($k == 0) {
                    $button = "<span class='btn-borderless' onclick='addRow(this)'>添加</span>";
                } else {
                    $button = "<span class='btn-borderless' onclick='decRow(this)'>删除</span>";
                }
                $input       = hidden(array('name' => 'mxId[]', 'value' => $array['id'])) .
                    select(array('name' => 'problem[]', 'title' => '请选择', 'value' => $array['problem'], 'option' => $defectOption)) .
                    text(array('name' => 'num[]', 'other' => self::digitalFiltering('numPrecision'), 'title' => '数量', 'value' => self::lostZero($array['num'], 'numPrecision')));
                $clockRuleTr .= <<<efo
<div class='item_row flex-box'>{$input}{$button}</div>
efo;
            }
        } else {
            $button      = "<span class='btn-borderless' style='margin-top: 0' onclick='addRow(this)'>添加</span>";
            $input       = hidden(array('name' => 'mxId[]', 'value' => self::getId())) .
                select(array('name' => 'problem[]', 'title' => '请选择', 'option' => $defectOption)) .
                text(array('name' => 'num[]', 'title' => '数量', 'other' => self::digitalFiltering('numPrecision'), 'value' => ''));
            $clockRuleTr .= <<<efo
<div class='item_row flex-box'>{$input}{$button}</div>
efo;
        }
        $materialName       = $sourceOrder['id'] ? materialClass::getName($sourceOrder['materialId']) : '';
        $sourceOrder['num'] = self::lostZero($sourceOrder['num'], 'numPrecision');
        $planNum            = $sourceOrder['id'] ? ($sourceOrder['num'] . ' ' . $sourceOrder['unit']) : 0;

        $line     = query('product_line', "id = '$sourceOrder[lineId]'");
        $lineName = $line['workshop'] . '-' . $line['name'];

        $process_report_staff = query('process_report_staff', "orderId = '$info[id]' order by list asc");
        $teamType             = explode('，', para('teamType'));
        $teamDetail           = query(
            'team_detail as a join team as b on a.orderId = b.id',
            "a.stid = '" . self::$stid . "' and b.coid = '" . self::$coid . "' and b.state = '启用'", "b.id as id"
        );
        $teamDetail['id']     = $teamDetail['id'] ?? '';
        $info['teamId']       = $info['teamId'] ?: $teamDetail['id'];
        $hide                 = 'hide';
        if ($info['valuationType'] == '个人计件') {
            $hide                         = '';
            $process_report_staff['stid'] = $process_report_staff['stid'] ?: self::$stid;
        }
        //表单
        $html = $this->layerEdit([
            "table" => [
                array(
                    must . "生产派工单号/生产流转卡：" => hidden(array('name' => 'sendId', 'value' => $info['sendId'])) . "<span id='machiningOrder'>{$sourceOrder['orderNo']}</span><span class='del-row-button' style='margin-left: 5px;cursor: pointer' onclick=\"layer('{$this->get('cla')}','addMaterial',{})\">选择</span>",
                    must . "工序：" => "<div id='process'>" . $process['name'] . "</div>" . hidden(array('name' => 'processId', 'value' => $process['id'])),
                ),
                array(
                    "计价方式：" => "<div id='valuationType'>" . $info['valuationType'] . "</div>",
                    "生产线：" => "<span id='line'>{$lineName}</span>",
                ),
                array(
                    "物料：" => "<span id='material'>{$materialName}</span>",
                ),
                array(
                    '计划数量：' => "<span id='machiningNum'>{$planNum}</span>，已报工数量<span id='reportNum'>$reportNum {$sourceOrder['unit']}</span>" . componentClass::tipComponent('包含本次报工且未判断已确认状态的数量') . "<span id='preProcess'>$preProcess</span>",
                ),
                array(
                    must . "班次：" => text(array("name" => "teamNo", "laydate" => array(), "value" => $info['id'] ? $info['teamNo'] : $this->date)) .
                        select(array('name' => 'teamType', 'option' => $teamType, 'title' => '请选择', 'value' => $info['teamType'] ?: $teamType[0])),
                    must . "班组：" => selectMultiple(array("name" => "teamId", 'value' => $info['teamId'], "title" => "班组", "table" => "team", 'change' => 'getTeamStaff', 'where' => " state ='启用' and coid = '" . self::$coid . "'", 'sqlField' => 'name', 'sqlId' => 'id')) . "<span id='teamStaff' class='$hide width200'>" . selectMultiple(array("name" => "teamStaffId", 'value' => $process_report_staff['stid'], "title" => "员工", "table" => "staff", 'where' => "stid in (select stid from team_detail where orderId = '$info[teamId]' and coid = '" . self::$coid . "')", 'sqlField' => 'name', 'sqlId' => 'stid')) . "</span>",
                ),
                array(
                    must . "产量：" => text(array("name" => "yield", 'other' => self::digitalFiltering('numPrecision'), "value" => self::lostZero($info['yield'], 'numPrecision'))),
                    "关联设备：" => selectMultiple(array("name" => "deviceId", 'value' => $info['deviceId'], "title" => "设备", 'where' => "coid = '" . self::$coid . "'", "table" => "equipment", 'sqlField' => 'name', 'sqlId' => 'id')),
                ),
                array(
                    "不良品数量：" => text(array("name" => "badNum", 'other' => self::digitalFiltering('numPrecision'), "value" => self::lostZero($info['badNum'], 'numPrecision'))),
                ),
                array(
                    "开始结束时间：" => text(array("name" => "startTime", 'laydate' => ['type' => 'datetime'], "value" => self::null($info['startTime'], false))) . '- ' . text(array("name" => "endTime", 'laydate' => ['type' => 'datetime'], "value" => self::null($info['endTime'], false))),
                ),
                array(
                    "缺陷类型：" => "<div class='row-li'>" . $clockRuleTr . "</div>",
                ),
                array(
                    "作业指导书：" => "<div id='fileHtml'>" . fileUploadClass::showSingFile($info['routingId'], '工艺路线指导书') . "</div>"
                ),
                array(
                    "备注：" => textarea(array("name" => "text", "value" => $info['text'])),
                ),
            ],
        ]);
        $html .= $this->js();
        //返回
        return $this->layer(array("title" => L('job.button.editor').self::title, "height" => 600, "html" => $html));
    }

    public function js(): string
    {
        return <<<efo
<style>
.row-li{width: 100%;}
.row-li .item_row{gap: 4px;}
.row-li .btn-borderless {width: 100px;}
/*.item_row{margin: 5px 0}
.layerList > ul > li:nth-child(2n-1) {width: 190px;}
.left-bottom {
    left: 234px;
}*/
</style>
<script>
//获取班组员工
function getTeamStaff(e){
       let teamId = e.value;
       $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=getTeamStaff',{teamId:teamId},function (res){
             $("#teamStaff").html(res.html)
         },'json');
}
 //添加一行
function addRow(e){
     let processId = $(e).closest('form').find("[name='processId']").val();
     if (!processId){
         msg('请先选择工序','error');
     }else{
         $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addRow',{processId:processId},function (res){
             $(".row-li").append(res.data);
         },'json');
     }
}
//选择生产产品
function addMaterial(){
     $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addMaterialEdit',$("form[name='mxForm']").serialize(),function(res) {
         if (res.warn ==2){
            $('#processReportAddMaterial').hide();
            $("#machiningNum").html(res.planNum+res.unit);
            $("[name='yield']").val(res.planNum);
             $("#reportNum").html(res.reportNum+res.unit);
            $("#process").empty().append(res.process);
            $("[name='processId']").val(res.processId);
            $("#machiningOrder").html(res.orderNo);
            $("#line").html(res.lineName);
            $("#material").html(res.materialName);
            $("[name='sendId']").val(res.id);
            $(".row-li").find("[name='problem[]']").empty().append(res.problem);
            if (res.valuationType =='班组计件'){
                $("#teamStaff").hide();
            }else if(res.valuationType =='个人计件'){
                 $("#teamStaff").show();
            }
            $("#valuationType").html(res.valuationType);
            $("#preProcess").html(res.preProcess)
            $("#fileHtml").empty().append(res.file)
         }else{
             msg(res.warn);
         }
    },'json');
}
</script>
efo;
    }

    /**
     * 根据班组获取员工
     */
    public function getTeamStaff()
    {
        $teamId       = $this->post('teamId');
        $json['html'] = selectMultiple(array("name" => "teamStaffId", "title" => "员工", "table" => "staff", 'where' => "stid in (select stid from team_detail where orderId = '$teamId' and coid = '" . self::$coid . "')", 'sqlField' => 'name', 'sqlId' => 'stid'));
        return json_encode($json, 320);
    }

    /**
     * 添加一行
     *
     * @return bool|string
     */
    public function addRow()
    {
        $process      = query('process', "id = '" . $this->post('processId') . "'");
        $defectOption = $process['id'] ? explode('，', $process['defectType']) : [];
        $json['data'] = "<div class='item_row flex-box'>" . hidden(array('name' => 'mxId[]', 'value' => self::getId())) . select(array('name' => 'problem[]', 'title' => '请选择', 'value' => '', 'option' => $defectOption)) . text(array('name' => 'num[]', 'title' => '数量', 'value' => '')) . "<span class='btn-borderless' onclick='decRow(this)'>删除</span></div>";
        return json_encode($json, 320);
    }

    /*编辑*/
    public function editEdit()
    {
        $id          = $this->post('id') ?: self::getId();
        $problemArr  = $this->post('problem') ?: [];
        $numArr      = $this->post('num') ?: [];
        $mxIdArr     = $this->post('mxId') ?: [];
        $teamStaffId = $this->post('teamStaffId');
        //赋值
        $field         = array(
            "startTime" => $this->post('startTime'),
            "endTime"   => $this->post('endTime'),
            "sendId"    => $this->post('sendId'),//备注
            'teamNo'    => $this->post('teamNo'),
            "teamType"  => $this->post('teamType'),
            "teamId"    => $this->post('teamId'),
            "deviceId"  => $this->post('deviceId'),
            "yield"     => $this->post('yield') ? self::formattingFigure($this->post('yield'), 'numPrecision') : 0,
            "badNum"    => $this->post('badNum') ? self::formattingFigure($this->post('badNum'), 'numPrecision') : 0,
        );
        $isProductCard = optionSettingClass::getSettingItem('生产', 'productCtrlMethod') == 'productCard';
        $warn          = '';
        if ($isProductCard) {
            $machining_card_detail     = query('machining_card_detail', "id = '$field[sendId]'");
            $field['sendId']           = $machining_card_detail['id'];
            $sourceOrder               = query('machining_card', "id = '$machining_card_detail[orderId]'");
            $field['routingMxId']      = $machining_card_detail['routingMxId'];
            $routingMx                 = query('routing_detail', "id = '$field[routingMxId]'");
            $field['processId']        = $machining_card_detail['processId'];
            $field['sourceTable']      = 'machining_card_detail';
            $field['machiningOrderId'] = $sourceOrder['sourceId'];
            $reportNum                 = find(array('table' => self::table, 'where' => "sendId = '$machining_card_detail[id]' and id !='$id'", 'sum' => "yield"));
            //获取上一节点工序
            $routingMx['list'] = (int)$routingMx['list'];
            $preProcessNode    = query('routing_detail', "orderId = '$sourceOrder[routingId]' and mark = '是' and isOut = '否' and list < $routingMx[list] order by list desc");
            $preCardDetail     = query('machining_card_detail', "orderId = '$machining_card_detail[orderId]' and routingMxId = '$preProcessNode[id]'");
            $preReportNum      = find(array('table' => self::table, "single" => "sendId = '$preCardDetail[id]' and state = '已确认'", 'field' => "ifnull(sum((yield-badNum)),0) as num"))['num'];
            if (!empty($preProcessNode['id']) && self::formattingFigure($field['yield'] + $reportNum, 'numPrecision') > $preReportNum) {
                //判断是否已超出上一节点的报工数量
                $process = query('process', "id = '$preProcessNode[processId]'");
                $warn    = "报工总数量已超出了上一工序节点【{$process['name']}】的合格数量";
            }
        } else {
            $sourceOrder               = query('machining_send_order', "id = '$field[sendId]'");
            $field['sendId']           = $sourceOrder['id'];
            $field['routingMxId']      = $sourceOrder['routingMxId'];
            $field['processId']        = $sourceOrder['processId'];
            $field['sourceTable']      = 'machining_send_order';
            $field['machiningOrderId'] = $sourceOrder['machiningOrderId'];
            $reportNum                 = find(array('table' => self::table, 'where' => "sendId = '$sourceOrder[id]' and id !='$id'", 'sum' => "yield"));
        }
        if (self::formattingFigure($field['yield'] + $reportNum, 'numPrecision') > $sourceOrder['num']) {
            $warn = "此工序的报工总数量已超过计划数量";
        }

        $field['orderNum'] = $sourceOrder['num'];
        $field['materialId'] = $sourceOrder['materialId'];
        $field['routingId']  = $sourceOrder['routingId'];
        $field['lineId']     = $sourceOrder['lineId'];
        $field['unit']       = $sourceOrder['unit'];

        $routing_detail         = query('routing_detail', "id = '$field[routingMxId]'");
        $field['valuationType'] = $routing_detail['valuationType'];
        $annotation             = [
            "sendId"        => '来源单据',
            'teamNo'        => '班次',
            "teamType"      => '班次',
            "teamId"        => '班组',
            "yield"         => '产量',
            "processId"     => '工序',
            "materialId"    => '物料ID',
            "routingId"     => '工艺路线',
            "routingMxId"   => '工艺路线明细',
            "lineId"        => '生产线',
            "valuationType" => '计件方式',
            "unit"          => '单位',
        ];
        $rules                  = [
            "sendId"        => 'required',
            'teamNo'        => 'required',
            "teamType"      => 'required',
            "teamId"        => 'required',
            "yield"         => 'required|numeric',
            'processId'     => 'required',
            "materialId"    => 'required',
            "routingId"     => 'required',
            'routingMxId'   => 'required',
            "lineId"        => 'required',
            "valuationType" => 'required',
            "unit"          => 'required',
        ];

        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
            goto resp;
        }
        $info = query(self::table, " id = '" . $id . "' ");
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "权限不足";
        } elseif ($info['state'] == '已确认') {
            $json['warn'] = '此报工已确认，不能编辑';
        } elseif (!empty($field['startTime']) && !empty($field['endTime']) && strtotime($field['endTime']) < strtotime($field['startTime'])) {
            $json['warn'] = '结束时间不能小于开始时间';
        } elseif ($warn) {
            $json['warn'] = $warn;
        } else {
            $this->startTrans();
            if (empty($info['id'])) {
                $userNo       = codeTemplateClass::generateCode(self::page, [
                    'prefix' => 'BG' . date('Ymd', strtotime($field['teamNo'])),
                    'table'  => self::table,
                    'field'  => 'orderNo',
                    'where'  => " and coid = '" . self::$coid . "'",
                ], $field);
                $field        = array_merge($field, array("id" => $id, 'coid' => self::$coid, 'orderNo' => $userNo, 'state' => '草稿', 'stid' => $this->control['stid']));
                $json['warn'] = insert(array("table" => self::table, "field" => $field));
            } else {
                $json['warn']     = update(array("table" => self::table, "field" => $field, "where" => "id = '$info[id]'"));
                $field['orderNo'] = $info['orderNo'];
            }
            $newIdArr = [];
            if (is_array($mxIdArr)) {
                foreach ($mxIdArr as $k => $mxId) {
                    if (!empty($problemArr[$k])) {
                        $newIdArr[] = $mxId;
                        $mx         = query(self::tableMx, "id = '$mxId'");
                        if (!empty($mx['id'])) {
                            $warn = static::update(array(
                                'table' => self::tableMx,
                                'field' => array(
                                    'problem' => $problemArr[$k],
                                    'num'     => $numArr[$k],
                                ),
                                'where' => "id = '$mx[id]'",
                            ));
                        } else {
                            $warn = static::insert(array(
                                'table' => self::tableMx,
                                'field' => array(
                                    'id'      => $mxId,
                                    'coid'    => self::$coid,
                                    'orderId' => $id,
                                    'problem' => $problemArr[$k],
                                    'num'     => $numArr[$k],
                                ),
                            ));
                        }
                        if (!in_array($warn, array("新增成功", "更新成功"))) {
                            $json['warn'] = $warn;
                            break;
                        }
                    }
                }
            }
            if ($field['valuationType'] == '个人计件') {
                delete(array('table' => self::tableStaff, 'where' => "orderId = '$id'"));
                $warn = static::insert(array(
                    'table' => self::tableStaff,
                    'field' => array(
                        'id'      => suiji(),
                        'coid'    => self::$coid,
                        'orderId' => $id,
                        'stid'    => $teamStaffId,
                    ),
                ));
                if (!in_array($warn, array("新增成功", "更新成功"))) {
                    $json['warn'] = $warn;
                }
            }

            if (in_array($json['warn'], array("新增成功", "更新成功"))) {
                $this->commitTrans();
                delete(array('table' => self::tableMx, 'where' => " id not in ('" . implode("','", $newIdArr) . "') and orderId = '$id'"));
                if ($json['warn'] == '新增成功') {
                    auditClass::operateRecord($info['id'], '工序报工', '新建');
                }
                $process = query('process', "id = '$field[processId]'");
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . ",单号【{$field['orderNo']}】,工序【{$process['name']}】,ID：" . $id;
                $this->logText(array("type" => self::page, "text" => $text));
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
            } else {
                $this->rollback();
            }
        }
        $json['href'] = root . "control/adIndex.html?cla=" . self::page . "&fun=detail&id=" . $id;

        resp:
        return json_encode($json, 320);
    }

    /**
     * 生成质检单
     */
    public function qualityOrder($id): bool|string
    {
        $bool = true;
        $info = query(self::table, "id = '$id'");
        //获取当前工艺路线的工序是否质检
        $routing_detail       = query('routing_detail', "id = '$info[routingMxId]'");
        if (in_array($routing_detail['method'], ['免检', '巡检', '自检'])) {
            return $bool;
        }
        $process = query('process', "id = '$info[processId]'");
        if (empty($process['id'])) {
            return "未找到工序";
        }
        if (empty($process['qualityItem'])) {
            return "请填写工序【{$process['name']}】的质检项";
        }
        $userNo = codeTemplateClass::generateCode('processingInspection', [
            'prefix' => 'IF' . date('Ymd'),
            'table'  => 'quality_order',
            'field'  => 'orderNo',
            'where'  => " and coid = '" . self::$coid . "'",
        ], []);
        $id     = self::getId();
        $num    = $info['yield'];
        $warn   = static::insert(array(
            'table' => 'quality_order',
            'field' => [
                'id'          => $id,
                'type'        => 4,
                'coid'        => self::$coid,
                'sourceTable' => self::table,
                'sourceId'    => $info['id'],
                'targetId'    => $info['lineId'],
                'inventoryId' => '',
                'warehouseId' => '',
                'num'         => $num,
                'materialId'  => $info['materialId'],
                'unit'        => $info['unit'],
                'processId'   => $info['processId'],
                'orderNo'     => $userNo,
                'batch'       => $userNo . '-' . 1,
                'qid'         => '',
                'sourceNo'    => $info['orderNo'],
                'sourceType'  => '工序报工',
                'state'       => '待质检',
            ],
        ));
        if ($warn != '新增成功') {
            return "新增质检单失败";
        }
        $all = explode('，', $process['qualityItem']);
        foreach ($all as $val) {
            $warn = static::insert(array(
                'table' => 'quality_order_item',
                'field' => [
                    'id'      => self::getId(),
                    'coid'    => self::$coid,
                    'orderId' => $id,
                    'itemId'  => $val,
                ],
            ));
            if ($warn != '新增成功') {
                return "新增质检单明细质检项目失败";
            }
        }
        return $bool;
    }

    /*出差详情*/
    public function detail(): string
    {
        //定义参数
        if (empty($this->get('id'))) {
            $html = '未找到此' . self::title;
        } else {
            $info = query(self::table, " id = '" . $this->get('id') . "' ");
            if (empty($info['id'])) {
                $html = "未找到此记录";
            } else {
                //菜单
                $data = array(
                    "id" => $info['id'],
                );

                $button = [];
                if ($info['state'] == '草稿') {
                    //按钮
                    $button[] = [
                        "name"  => "提交",
                        "type"  => "弹出层",
                        "cla"   => $this->get('cla'),
                        "fun"   => "operate",
                        "post"  => ["act" => 'commit', "id" => $info['id']],
                        'style' => 'li-btn-blue-bg',
                    ];
                }
                if ($info['state'] != '已确认') {
                    if ($this->power(self::page, "edit")) {
                        //按钮
                        $button[] = [
                            "name"  => "编辑",
                            "type" => "弹出层",
                            "cla" => $this->get('cla'),
                            "fun" => "edit",
                            "post" => ["id" => $info['id']],
                        ];
                    }
                    if ($this->power(self::page, "del")) {
                        //按钮
                        $button[] = [
                            "name" => "删除",
                            "type" => "弹出层",
                            "cla"  => $this->get('cla'),
                            "fun"  => "operate",
                            "post" => ["act" => 'del', "id" => $info['id']],
                        ];
                    }
                }

                if ($this->power(self::page, "confirm") && $info['state'] == '待确认') {
                    $button[] = [
                        "name"  => "确认",
                        "type"  => "弹出层",
                        "cla"   => $this->get('cla'),
                        "fun"   => "operate",
                        "post"  => ["act" => 'confirm', "id" => $info['id']],
                        'style' => 'li-btn-blue-bg',
                    ];
                }
                if ($this->power(self::page, "cancel") && $info['state'] == '已确认') {
                    $button[] = [
                        "name" => "撤回",
                        "type" => "弹出层",
                        "cla"  => $this->get('cla'),
                        "fun"  => "operate",
                        "post" => ["act" => 'cancel', "id" => $info['id']],
                    ];
                }
                //操作记录
                $button[] = self::operateLogBut($info['id']);

                if ($info['sourceTable'] == 'machining_card_detail') {
                    $machining_card_detail = query('machining_card_detail', "id = '$info[sendId]'");
                    $sourceOrder           = query('machining_card', "id = '$machining_card_detail[orderId]'");
                    $machiningSendOrder    = query('machining_order', "id = '$sourceOrder[sourceId]'");
                } else {
                    $sourceOrder        = query($info['sourceTable'], "id = '$info[sendId]'");
                    $machiningSendOrder = $sourceOrder;
                }
                $line          = query('product_line', "id = '$info[lineId]'");
                $process       = query('process', "id = '$info[processId]'");
                $team          = query('team', "id = '$info[teamId]'");
                $mxStr         = find(array('table' => self::tableMx, "single" => "orderId = '$info[id]' group by orderId", 'field' => "group_concat(concat(any_value(problem),',',any_value(num))) as str"));
                $teamStaff     = query('process_report_staff', "orderId = '$info[id]' order by list");
                $teamStaffName = $info['valuationType'] == '个人计件' ? '-' . self::findStaff($teamStaff['stid']) : '';

                //生成表单
                $data['button'] = $this->tableShowButton($button);
                $data['html'] = $this->tableShow(array(
                    "基本信息" => array(
                        array(
                            "报工单号"         => $info['orderNo'],
                            '生产线'          => $line['workshop'] . '-' . $line['name'],
                            "派工单号/生产流转卡单号" => $sourceOrder['orderNo'],
                            "工序"   => $process['name'],
                        ),
                        array(
                            "计价方式" => $info['valuationType'],
                            "关联设备" => equipmentClass::getName($info['deviceId']),
                            "物料"   => materialClass::getName($info['materialId']),
                            "生产数量" => self::lostZero($sourceOrder['num'], 'numPrecision') . $info['unit'],
                        ),
                        array(
                            "计划开始时间" => $machiningSendOrder['startDate'],
                            "计划下线时间" => $machiningSendOrder['endDate'],
                        ),
                        array(
                            '作业指导书' => fileUploadClass::showSingFile($info['routingId'], '工艺路线指导书')
                        ),
                        array(
                            "备注" => pre($machiningSendOrder['text']),
                        ),
                    ),
                    '报工记录'   => array(
                        array(
                            "班次" => $info['teamNo'] . '-' . $info['teamType'],
                            "班组" => $team['name'] . $teamStaffName,
                            "产量" => self::lostZero($info['yield'], 'numPrecision') . ' ' . $info['unit'],
                            "不良数量"   => self::lostZero($info['badNum'], 'numPrecision') . $info['unit'],
                        ),
                        array(
                            "缺陷类型"   => $mxStr['str'] ?? '',
                            "开始结束时间" => $info['startTime'] . '至' . $info['endTime'],
                        ),
                        array(
                            "备注" => pre($info['text']),
                        ),
                    ),
                    '系统信息'   => array(
                        array(
                            "创建人"  => self::findStaff($info['stid']),
                            "创建时间" => $info['time'],
                            "状态" => $info['state']
                        ),
                    ),
                ));
                //生成页面
                $html = $this->tab($data);
            }
        }
        //返回
        return $html;
    }


    /**
     * 确认
     */
    public function confirmEdit()
    {
        $id    = $this->post('id');
        $info  = query(self::table, " id = '$id'");
        $field = [
            'state'       => '已确认',
            'checkId'     => self::$stid,
            'confirmTime' => $this->time,
        ];

        if (!$this->power(self::page, 'confirm')) {
            $json['warn'] = '你还没有确认权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此' . self::title;
        } elseif ($info['state'] != '待确认') {
            $json['warn'] = '此' . self::title . '不是待确认状态，不能确认';
        } else {
            $this->startTrans();
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));
            if ($info['valuationType'] == '班组计件') {
                $teamMx = find(array('table' => 'team_detail', "where" => "orderId = '$info[teamId]' order by list asc"));
                foreach ($teamMx['array'] as $array) {
                    $warn = static::insert(array(
                        'table' => self::tableStaff,
                        'field' => [
                            'id'      => self::getId(),
                            'orderId' => $info['id'],
                            'stid'    => $array['stid'],
                            'coid'    => self::$coid,
                        ],
                    ));
                    if ($warn != '新增成功') {
                        $json['warn'] = $warn;
                        break;
                    }
                }
            }
            $bool = $this->qualityOrder($info['id']);
            if ($bool !== true) {
                $json['warn'] = $bool;
            }

            /********增加工序库存表数据（以报工数量为准，先不管质检）**************/
            $bool = $this->setInventory($info);
            if ($bool !== true) {
                $json['warn'] = $bool;
            }
            /*********尾工序自动生成生产入库单************/
            $routingMx = query('routing_detail', "id = '$info[routingMxId]'");
            $routing   = query('routing', "id = '$routingMx[orderId]'");
            //尾工序
            $endRoutingDetail = query('routing_detail', "orderId = '$routing[id]' order by list desc");
            $state            = '';
            if ($routingMx['id'] == $endRoutingDetail['id'] && $routing['endProcessIn'] == '是') {
                $mainId = suiji();
                $userNo = codeTemplateClass::generateCode('machiningInOrder', [
                    'prefix' => 'SCRK' . date('Ymd', strtotime($info['teamNo'])),
                    'table'  => 'machining_in_order',
                    'field'  => 'orderNo',
                    'where'  => " and coid = '" . self::$coid . "'",
                ], []);
                if ($info['sourceTable'] == 'machining_card_detail') {
                    $machining_card_detail = query('machining_card_detail', "id = '$info[sendId]'");
                    $sourceOrder           = query('machining_card', "id = '$machining_card_detail[orderId]'");
                    $machiningOrderMxId    = $sourceOrder['sourceMxId'];
                } else {
                    $sourceOrder        = query('machining_send_order', "id = '$info[sendId]'");
                    $machiningOrderMxId = $sourceOrder['machiningOrderMxId'];
                }
                $machiningOrderMx = query('machining_order_mx', "id = '$machiningOrderMxId'");

                $material = query('material', "id = '$info[materialId]'");
                $state    = $material['warehouse'] ? '已确认' : '草稿';
                $warn     = static::insert(array(
                    'table' => 'machining_in_order',
                    'field' => [
                        'id'         => $mainId,
                        'orderNo'    => $userNo,
                        'state'      => $state,
                        'coid'       => self::$coid,
                        'stid'       => $this->control['stid'],
                        'text'       => '尾工序自动生成',
                        'lineId'     => $info['lineId'],
                        'manager'    => $info['stid'],
                        'recordDate' => $info['teamNo'],
                    ],
                ));
                if ($warn !== '新增成功') {
                    $json['warn'] = $warn;
                }
                $warn = static::insert([
                    "table" => 'machining_in_order_detail',
                    "field" => [
                        'id'          => suiji(),
                        'orderId'     => $mainId,
                        'coid'        => self::$coid,
                        'sourceId'    => $machiningOrderMxId,
                        'materialId'  => $info['materialId'],
                        'num'         => $info['yield'],
                        'unit'        => $sourceOrder['unit'],
                        'warehouseId' => $material['warehouse'],
                        'batch'       => $machiningOrderMx['batch'],
                        'reportId'    => $info['id']
                    ],
                ]);
                if ($warn !== '新增成功') {
                    $json['warn'] = $warn;
                }
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $this->commitTrans();
                auditClass::operateRecord($info['id'], '工序报工', '确认');
                if ($routingMx['id'] == $endRoutingDetail['id'] && $routing['endProcessIn'] == '是' && $state == '已确认') {
                    $mainId                = $mainId ?? '';
                    $machiningInOrder      = query('machining_in_order', "id = '$mainId'");
                    $machiningInOrderClass = new machiningInOrderClass();
                    $machiningInOrderClass->insertInventory($machiningInOrder, false);
                }
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = '确认成功';
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 生成工序库存变动记录
     */
    public function setInventory($info)
    {
        $bool = processInventoryClass::iData([
            'materialId' => $info['materialId'],
            'processId'  => $info['processId'],
            'sourceId'   => $info['id'],
            'num'        => $info['yield'] - $info['badNum'],
            'text'       => "工序报工【{$info['orderNo']}】",
        ]);
        if ($bool != '新增成功') {
            return '生成工序库存失败';
        }
        $routingMx = query('routing_detail', "id = '$info[routingMxId]'");
        //前一工序
        $preProcessNode = query('routing_detail', "orderId = '$info[routingId]' and isOut = '否' and list < $routingMx[list] order by list desc");
        if (!empty($preProcessNode['id'])) {
            //如果存在前一工序且不是委外工序，则扣除前一工序的数量
            $bool = processInventoryClass::iData([
                'materialId' => $info['materialId'],
                'processId'  => $preProcessNode['processId'],
                'sourceId'   => $info['id'],
                'num'        => -($info['yield'] - $info['badNum']),
                'text'       => "工序报工【{$info['orderNo']}】，前一工序【{$preProcessNode['processId']}】扣除",
            ]);
            if ($bool != '新增成功') {
                return '生成工序库存扣除失败';
            }
        }
        return true;
    }

    /**
     * 撤回
     */
    public function cancelEdit()
    {
        $id    = $this->post('id');
        $info  = query(self::table, " id = '$id'");
        $field = [
            'state'       => '草稿',
            'checkId'     => '',
            'confirmTime' => '',
        ];
        if (!$this->power(self::page, 'cancel')) {
            $json['warn'] = '你还没有撤回权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此工序报工';
        } elseif ($info['state'] != '已确认') {
            $json['warn'] = '此工序报工不是已确认状态，无需撤回';
        } elseif (static::total(array('table' => 'quality_order', "where" => "sourceId = '$info[id]' and coid = '" . self::$coid . "' and state ='已质检'")) > 0) {
            $json['warn'] = '此报工单已存在有已质检的单据，不能撤回';
        } elseif (self::total(array('table' => 'machining_in_order_detail as a join machining_in_order as b on a.orderId = b.id', "where" => "a.reportId = '$info[id]' and a.coid = '" . self::$coid . "' and b.state ='已确认'")) > 0) {
            $json['warn'] = '此报工单已存在有已确认的生产入库单据，不能撤回';
        } else {
            $this->startTrans();
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));
            $bool         = processInventoryClass::delData($info['id']);
            if ($bool != '删除成功') {
                $json['warn'] = '删除工序库存记录失败';
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $this->commitTrans();
                delete(array('table' => self::tableStaff, 'where' => "orderId = '$info[id]'"));
                //删除生产入库单
                delete(array('table' => 'machining_in_order', 'where' => "id in (select orderId from machining_in_order_detail where reportId = '$info[id]' and coid = '" . self::$coid . "')"));
                delete(array('table' => 'machining_in_order_detail', 'where' => "reportId = '$info[id]' and coid = '" . self::$coid . "'"));
                //删除质检单
                delete(array('table' => 'quality_order_item', 'where' => "orderId in (select id from quality_order where sourceId = '$info[id]' and coid = '" . self::$coid . "')"));
                delete(array('table' => 'quality_order_reason', 'where' => "orderId in (select id from quality_order where sourceId = '$info[id]' and coid = '" . self::$coid . "')"));
                delete(array('table' => 'quality_order', 'where' => "sourceId = '$info[id]'"));
                auditClass::operateRecord($info['id'], '工序报工', '撤回');
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = '撤回成功';
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 提交
     */
    public function commitEdit()
    {
        $id    = $this->post('id');
        $info  = query(self::table, " id = '$id'");
        $field = [
            'state' => '待确认',
        ];
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此工序报工';
        } elseif ($info['state'] != '草稿') {
            $json['warn'] = '此工序报工不是草稿状态，不能提交';
        } else {
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                auditClass::operateRecord($info['id'], '工序报工', '提交');
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = '提交成功';
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 删除
     *
     * @return bool|string
     */
    public function delete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
                if ($info['state'] == '已确认') {
                    $warn = "删除失败：已确认，暂不能删除";
                } else {
                    //最后删除基本参数
                    delete(array("table" => self::table, "where" => " id = '$id' "));
                    delete(array("table" => self::tableMx, "where" => " orderId = '$id' "));
                    delete(array("table" => "auditing_follow", "where" => " typeId = '$id' "));
                    //返回
                    $warn = "删除成功";
                    $x++;
                }
                $text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

    // 操作中转
    public function operate()
    {
        $act  = $this->post('act') ?? '';
        $pwd  = false; // 需要密码
        $form = $power = $word = '';
        switch ($act) {
            case 'confirm':
                $act      = 'confirm';
                $msg      = '确认';
                $title    = '是否已确认此' . self::title . '，确认后将不可修改？';
                $function = 'confirmEdit';
                $form     = self::page . 'OperateForm, detailForm';
                $power    = '';
                $word     = true;
                break;
            case 'commit':
                $act      = 'edit';
                $msg      = '编辑';
                $title    = '是否确认提交此' . self::title . '？';
                $function = 'commitEdit';
                $form     = self::page . 'OperateForm, detailForm';
                $power    = '';
                $word     = true;
                break;
            case 'cancel':
                $act      = 'cancel';
                $msg      = '撤回';
                $title    = '是否确认撤回此' . self::title . '？';
                $function = 'cancelEdit';
                $form     = self::page . 'OperateForm, detailForm';
                $power    = '';
                $word     = true;
                break;
            default:
                $act      = 'del';
                $msg      = '删除' . self::title;
                $title    = self::page . 'Delete';
                $function = 'delete';
                $form     = self::page . 'OperateForm, listForm';
                $power    = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'word'     => $word,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }


    /**
     *选择生产产品
     *
     * @return bool|string
     */
    public function addMaterial(): bool|string
    {
        if (optionSettingClass::getSettingItem('生产', 'productCtrlMethod') == 'productCard') {
            //生成生产流转卡
            $title = '生产流转卡编号';
        } else {
            $title = '生产派工单号';
        }
        $html   =
            text(array("name" => "orderNo", "title" => $title)) .
            text(array('name' => 'code', 'title' => '产品编码')) .
            text(array('name' => 'materialName', 'title' => '产品名称')) .
            text(array('name' => 'model', 'title' => '产品型号'));
        $button = "<input style='margin-left: 5px' onclick=\"addMaterial()\" type='button' class='searchSub' value='提交'>";
        $html   = $this->search($html);
        return $this->layer(array("title" => "添加", "height" => 600, "width" => 1100, "zindex" => 3, "html" => $html, "button" => $button));
    }

    /**
     *添加物料
     */
    public function addMaterialSearch(): bool|string
    {
        if (optionSettingClass::getSettingItem('生产', 'productCtrlMethod') == 'productCard') {
            $json['html'] = $this->machiningCardSearch();
        } else {
            $and   = " and workFlow = 0 and isClose=0 and machiningOrderId not in (select id from machining_order where coid = '" . self::$coid . "' and isClose = 1)";
            $mAnd  = '';
            $like  = [
                'orderNo' => $this->post('orderNo'),
            ];
            $equal = [
                'coid'     => self::$coid,
                'classify' => '生产派工',
                'state'    => '已确认',
            ];

            if ($this->post('code')) {
                $mAnd .= " and code like '%" . $this->post('code') . "%'";
            }
            if ($this->post('materialName')) {
                $mAnd .= " and name like '%" . $this->post('materialName') . "%'";
            }
            if ($this->post('model')) {
                $mAnd .= " and model like '%" . $this->post('model') . "%'";
            }
            if ($mAnd) {
                $and .= " and materialId in (select id from material where 1=1 {$mAnd})";
            }
            $where = search(["like" => $like, "=" => $equal]) . $and;
            $page  = $this->page([
                "table"   => "machining_send_order",
                "where"   => $where,
                'pageNum' => 50,
                "order"   => "orderNo desc",
            ]);
            //获取表头
            $tr[] = ['', '生产派工单号', '单据日期', '生产线', '产品编码', '产品名称', '产品型号', '工序'];
            //获取记录
            foreach ($page['array'] as $array) {
                $material = query('material', "id = '$array[materialId]'");
                $line     = query('product_line', "id = '$array[lineId]'");
                $process  = query('process', "id = '$array[processId]'");
                $tr[]     = array(
                    "<input name='mxId' value='$array[id]' type='radio'>",
                    $array['orderNo'],
                    $array['recordDate'],
                    $line['workshop'] . '-' . $line['name'],
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $process['name'],
                );
            }
            $json['html'] = $page['hint'] . "<form name='mxForm'>" . $this->tableMany(array("tr" => $tr, "showSort" => true, "page" => $page['para'])) . "</form>" . $page['button'];
        }

        return json_encode($json, 320);
    }

    /**
     * 生产流转卡
     */
    public function machiningCardSearch()
    {
        $and   = " and a.sourceId not in (select id from machining_order where coid = '" . self::$coid . "' and isClose = 1)";
        $like  = [
            'a.orderNo' => $this->post('orderNo'),
            'c.code'    => $this->post('code'),
            'c.name'    => $this->post('materialName'),
            'c.model'   => $this->post('model'),
        ];
        $equal = [
            'a.coid' => self::$coid,
        ];
        $where = search(["like" => $like, "=" => $equal]) . $and;
        $page  = $this->page([
            "table"   => "machining_card as a join machining_card_detail as b on a.id = b.orderId join material as c on c.id = a.materialId",
            'field'   => "a.*,b.processId,b.id as mxId,c.name,c.code,c.model",
            "where"   => $where,
            'pageNum' => 50,
            "order"   => "a.orderNo desc,b.list asc",
        ]);
        //获取表头
        $tr[] = ['', '生产流转卡单号', '单据日期', '生产线', '工序', '产品编码', '产品名称', '产品型号'];
        //获取记录
        foreach ($page['array'] as $array) {
            $line    = query('product_line', "id = '$array[lineId]'");
            $process = query('process', "id = '$array[processId]'");
            $tr[]    = array(
                "<input name='mxId' value='$array[mxId]' type='radio'>",
                $array['orderNo'],
                $array['recordDate'],
                $line['workshop'] . '-' . $line['name'],
                $process['name'],
                $array['code'],
                $array['name'],
                $array['model'],
            );
        }
        return $page['hint'] . "<form name='mxForm'>" . space . $this->tableMany(array("tr" => $tr)) . "</form>" . $page['button'];
    }

    /**
     * 编辑
     *
     * @return bool|string
     */
    public function addMaterialEdit(): bool|string
    {
        $id = $this->post('mxId');
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (empty($id)) {
            $json['warn'] = '请选择数据';
        } else {
            $json['preProcess'] = "";
            $json['device']     = '';
            if (optionSettingClass::getSettingItem('生产', 'productCtrlMethod') == 'productCard') {
                $machining_card_detail = query('machining_card_detail', "id = '$id'");
                $sourceOrder           = query('machining_card', "id = '$machining_card_detail[orderId]'");
                $routingDetail         = query('routing_detail', "id = '$machining_card_detail[routingMxId]'");
                $process               = query('process', "id = '$machining_card_detail[processId]'");
                //取上一工序
                $preCardDetail = query('machining_card_detail', "orderId = '$machining_card_detail[orderId]' and list < $machining_card_detail[list] order by list desc");
                if (!empty($preCardDetail['id'])) {
                    $preProcess         = query('process', "id = '$preCardDetail[processId]'");
                    $reportNum      = find(array('table' => self::table, "single" => "sendId = '$preCardDetail[id]' and state = '已确认'", 'field' => "ifnull(sum((yield-badNum)),0) as num"))['num'];
                    $reportNum          = self::lostZero($reportNum, 'numPrecision');
                    $json['preProcess'] = "，上工序【{$preProcess['name']}】报工合格{$reportNum} " . $sourceOrder['unit'];
                }
                $json['reportNum'] = find(array('table' => self::table, 'where' => "sendId = '$machining_card_detail[id]'", 'sum' => "yield"));
            } else {
                $sourceOrder       = query('machining_send_order', "id = '$id'");
                $routingDetail     = query('routing_detail', "id = '$sourceOrder[routingMxId]'");
                $process           = query('process', "id = '$sourceOrder[processId]'");
                $json['reportNum'] = find(array('table' => self::table, 'where' => "sendId = '$sourceOrder[id]'", 'sum' => "yield"));
                $json['device']    = selectMultiple(array("name" => "deviceId", 'value' => $sourceOrder['deviceId'], "title" => "设备", 'where' => "coid = '" . self::$coid . "'", "table" => "equipment", 'sqlField' => 'name', 'sqlId' => 'id'));
            }
            $material              = query('material', "id = '$sourceOrder[materialId]'");
            $line                  = query('product_line', "id = '$sourceOrder[lineId]'");
            $lineName              = $line['workshop'] . '-' . $line['name'];
            $json['process']       = $process['name'];
            $json['processId']     = $process['id'];
            $json['valuationType'] = $routingDetail['valuationType'];
            $json['planNum']       = self::lostZero($sourceOrder['num'], 'numPrecision');

            $json['unit']         = $sourceOrder['unit'];
            $json['materialName'] = $material['code'] . '-' . $material['name'] . '-' . $material['model'];
            $json['id']           = $id;
            $json['orderNo']      = $sourceOrder['orderNo'];
            $json['lineName']     = $lineName;
            $json['problem']      = option(array('option' => $process['defectType'] ? explode('，', $process['defectType']) : [], 'title' => '请选择'));
            $json['file']         = fileUploadClass::showSingFile($sourceOrder['routingId'], '工艺路线指导书');

            $json['warn'] = 2;
        }
        return json_encode($json, 320);
    }

}
